﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows.Controls;
using System.Windows.Data;

namespace testProject.ViewModel
{
    public class MainPageViewModel:DependencyObject
    {
        //public ObservableCollection<string> Statuses
        //{
        //    get { return (ObservableCollection<string>)GetValue(StatusesProperty); }
        //    set { SetValue(StatusesProperty, value); }
        //}

        //// Using a DependencyProperty as the backing store for Statuses.  This enables animation, styling, binding, etc...
        //public static readonly DependencyProperty StatusesProperty =
        //    DependencyProperty.Register("Statuses", typeof(ObservableCollection<string>), typeof(MainPageViewModel), new UIPropertyMetadata(new ObservableCollection<string>()));

        public ObservableCollection<string> Statuses { get; set; }


        public string SelectedItem
        {
            get { return (string)GetValue(SelectedItemProperty); }
            set { SetValue(SelectedItemProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SelectedItem.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register("SelectedItem", typeof(string), typeof(MainPageViewModel), new UIPropertyMetadata(null));

        public MainPageViewModel()
        {
            SaveCommand = new SaveCommander(this);
            RemoveCommand = new RemoveCommander(this);
            AddCommand = new AddCommander(this);
            Statuses = new ObservableCollection<string>();
            for (int i = 0; i < 20; i++)
            {
                Statuses.Add(i.ToString());
            }

            SelectedItem = Statuses[Statuses.Count - 3];
        }
         
        public bool CanExecuted
        {
            get { return (bool)GetValue(CanExecutedProperty); }
            set { SetValue(CanExecutedProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CanExecuted.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CanExecutedProperty =
            DependencyProperty.Register("CanExecuted", typeof(bool), typeof(MainPageViewModel),
            new PropertyMetadata(false, 
                new PropertyChangedCallback((d,e)=>
                {
                    (d as MainPageViewModel).SaveCommand.ChangedStatus();
                })));
           
        public string Name
        {
            get { return (string)GetValue(NameProperty); }
            set { SetValue(NameProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Name.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty NameProperty =
            DependencyProperty.Register("Name", typeof(string),
            typeof(MainPageViewModel),
            new PropertyMetadata("Xianlong",
                new PropertyChangedCallback((d, e) =>
                {
                    (d as MainPageViewModel).CanExecuted = !string.IsNullOrEmpty(e.NewValue.ToString());
                }
            )));

        public void SaveName()
        {
            Name += "Saved at " + DateTime.Now.ToLongTimeString();
            CanExecuted = false;
        }

        public void RemoveStatus()
        {
            Statuses.RemoveAt(0);
            //SelectedItem = Statuses[4];
            CollectionViewSource.GetDefaultView(Statuses).MoveCurrentToFirst();
        }

        public SaveCommander SaveCommand
        {
            get { return (SaveCommander)GetValue(SaveCommandProperty); }
            set { SetValue(SaveCommandProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SaveCommand.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SaveCommandProperty =
            DependencyProperty.Register("SaveCommand", typeof(SaveCommander), typeof(MainPageViewModel), new PropertyMetadata(null));
         
        public MouseEnterCommander MouseEnterCommande
        {
            get { return (MouseEnterCommander)GetValue(MouseEnterCommandeProperty); }
            set { SetValue(MouseEnterCommandeProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MouseEnterCommande.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MouseEnterCommandeProperty =
            DependencyProperty.Register("MouseEnterCommande", typeof(MouseEnterCommander), typeof(MainPageViewModel), new UIPropertyMetadata(new MouseEnterCommander()));
         
        public RemoveCommander RemoveCommand
        {
            get { return (RemoveCommander)GetValue(RemoveCommandProperty); }
            set { SetValue(RemoveCommandProperty, value); }
        }

        // Using a DependencyProperty as the backing store for RemoveCommand.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty RemoveCommandProperty = 
            DependencyProperty.Register("RemoveCommand", typeof(RemoveCommander), typeof(MainPageViewModel), new UIPropertyMetadata(null));



        public AddCommander AddCommand
        {
            get { return (AddCommander)GetValue(AddCommandProperty); }
            set { SetValue(AddCommandProperty, value); }
        }

        // Using a DependencyProperty as the backing store for AddCommand.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty AddCommandProperty =
            DependencyProperty.Register("AddCommand", typeof(AddCommander), typeof(MainPageViewModel), new UIPropertyMetadata(null));



        public CopyCommander CopyCommand
        {
            get { return (CopyCommander)GetValue(CopyCommandProperty); }
            set { SetValue(CopyCommandProperty, value); }
        }

        // Using a DependencyProperty as the backing store for CopyCommand.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty CopyCommandProperty =
            DependencyProperty.Register("CopyCommand", typeof(CopyCommander), typeof(MainPageViewModel), new UIPropertyMetadata(new CopyCommander()));

        public class CopyCommander : ICommand
        {
            #region ICommand Members

            public bool CanExecute(object parameter)
            {
                return true;
            }

            public event EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                MessageBox.Show(parameter.ToString());
            }

            #endregion
        }


        public class AddCommander:ICommand
        {
            MainPageViewModel viewModel;
            public AddCommander(MainPageViewModel vm)
            {
                viewModel = vm;
            }

            public bool CanExecute(object parameter)
            {
                return true;
            }

            public event EventHandler CanExecuteChanged;

            public void ChangedStatus()
            {
                CanExecuteChanged(this, new EventArgs());
            }

            public void Execute(object parameter)
            {
                viewModel.Statuses.Add(DateTime.Now.ToLongTimeString());
            }
        }
        public class SaveCommander:ICommand
        {
            MainPageViewModel viewModel;
            public SaveCommander(MainPageViewModel vm)
            {
                viewModel = vm;
            }

            public bool CanExecute(object parameter)
            {
                return viewModel.CanExecuted;
            }

            public event EventHandler CanExecuteChanged;

            public void ChangedStatus()
            {
                CanExecuteChanged(this, new EventArgs());
            }

            public void Execute(object parameter)
            {
                viewModel.SaveName(); 
            }
        }
        public class RemoveCommander : ICommand
        {
            MainPageViewModel viewModel;
            public RemoveCommander(MainPageViewModel vm)
            {
                viewModel = vm;
            }

            public bool CanExecute(object parameter)
            {
                return true;
            }

            public event EventHandler CanExecuteChanged;

            public void ChangedStatus()
            {
                CanExecuteChanged(this, new EventArgs());
            }

            public void Execute(object parameter)
            {
                viewModel.RemoveStatus();
            }
        }
        public class MouseEnterCommander : ICommand
        {
            public MouseEnterCommander()
            {
            }

            public bool CanExecute(object parameter)
            {
                return true;
            }

            public event EventHandler CanExecuteChanged;

            public void Execute(object parameter)
            {
                object a = parameter ?? "no parameter";
                MessageBox.Show(a.ToString());
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;
    }
}
